# !/usr/local/bin/python3
# -*- encoding: utf-8 -*-
# @FileName :   Thread.py
# @DateTime :   2022/8/25 | 13:12
# @Author   :   IoTus3
# @GitHub   :   https://gitee.com/IoTus3
# @Contact  :   xianglin.fu3@gmail.com
# @License  :   (C)Copyright 2022-2023, LinYuStudio-NLPR-CASIA
# @Editor   :   Power by PyCharm
# @Desc     :   QT协程传输数据


# 爬虫类
from src.main.models.Spider import *
# 邮箱类
from src.main.models.MailSender import *
# smtp数据保存路径
from src.main.conf.conf import smtpPath
# 引入QT协程
from PySide6.QtCore import QThread, Signal
# 引入自带库
import time
import random
import datetime
import os


# 协程类
class NewTaskThread(QThread):
    # 信号，触发信号，更新窗体中的数据
    success = Signal(int, str, str, str, float)
    error = Signal(int, str, str, str)

    def __init__(self, row_index, asin, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.row_index = row_index
        self.asin = asin

    def run(self):
        """
        线程内部应该跑的东西
        :return:
        """
        try:
            amazon_spider = AmazonSpider(self.asin)
            wares, _ = amazon_spider.run()
            # print(wares.price)
            # 获取到asin, title, url, price
            self.success.emit(self.row_index, wares.asin, wares.title, wares.url, wares.price)
        except Exception as e:
            title = "监控项 {} 添加失败".format(self.asin)
            self.error.emit(self.row_index, self.asin, title, str(e))


class TaskThread(QThread):
    # 创建任务线程类

    # 信号，触发信号，更新窗体中的数据
    start_signal = Signal(int)
    counter_signal = Signal(int)
    fail_signal = Signal(int)
    price_signal = Signal(int, float)
    stop_signal = Signal(int)
    email_signal = Signal(str)

    def __init__(self, scheduler, log_file_path, row_index, asin, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.scheduler = scheduler
        self.row_index = row_index
        self.asin = asin
        self.log_file_path = log_file_path

    def run(self):
        # 触发信号
        self.start_signal.emit(self.row_index)

        # 获取当前行的价格
        current_row_price = float(self.scheduler.window.mainTable.item(self.row_index, 3).text().strip())
        title = self.scheduler.window.mainTable.item(self.row_index, 1).text().strip()

        # 自动更新成功次数
        while True:
            # 停止
            if self.scheduler.terminate:
                self.stop_signal.emit(self.row_index)
                # 自己的线程在thread_list里面被移除
                self.scheduler.distroy_thread(self)
                return
            time.sleep(random.randint(1, 3))
            amazon_spider = AmazonSpider(self.asin)
            wares, resp = amazon_spider.run()
            if resp.status_code == 200:
                self.counter_signal.emit(self.row_index)
                self.price_signal.emit(self.row_index, wares.price)

                # 如果当前价格小于当前价格的80%则发送邮件提醒
                if current_row_price * 0.8 > wares.price:
                    data_dict = {}
                    if os.path.exists(smtpPath):
                        with open(smtpPath, mode="r", encoding="utf-8") as fp:
                            data_dict = json.load(fp)
                    mailsender = MailSender(data_dict["smtp"], data_dict["from"], data_dict["pwd"], data_dict["to"],
                                            title, wares.price)
                    flag = mailsender.send()
                    if flag:
                        self.email_signal.emit("成功")
                    else:
                        self.email_signal.emit("失败")

            elif resp.status_code != 200:
                self.fail_signal.emit(self.row_index)

            # 无论成功还是失败都需要写入日志
            with open(self.log_file_path, mode="w", encoding="utf-8") as fp:
                content = str(datetime.datetime.now()) + "\n" + str(resp.status_code) + "\n" + str(resp.cookies) + "\n"
                fp.write(content)


# 停止线程
class StopThread(QThread):
    # 更新信号
    update_signal = Signal(str)

    def __init__(self, scheduler, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.scheduler = scheduler

    def run(self):
        # 监测线程对象
        # 总的线程数量
        total_count = len(self.scheduler.thread_list)
        while True:
            # 现在还剩余的线程数
            running_count = len(self.scheduler.thread_list)
            # 更新到页面上
            self.update_signal.emit("正在中止监测项:剩余{}|{}".format(total_count, running_count))
            # 结束标志
            if running_count == 0:
                break
            else:
                time.sleep(1)
        self.update_signal.emit("已中止全部监测项")
